Conversation
⚡ Risk Assessment —
|
| Files | Summary |
|---|---|
Changelogchangelog/14135.bugfix.rst |
New changelog entry documenting the ambiguous `-p` plugin module warning behavior. |
Ambiguous plugin detection logicsrc/_pytest/config/__init__.py |
Introduces `_warn_about_submodule_entrypoint_plugin` to detect when `-p` loads a module lacking pytest hooks while a `pytest11` entry-point with a submodule path exists, and `_plugin_has_pytest_hooks` to introspect whether a plugin defines any hook implementations. Emits a `PytestConfigWarning` suggesting the correct `-p` name. |
Tests for ambiguous plugin warningtesting/test_config.py |
Adds five test cases covering: warning emitted for single and multiple submodule entry-points, no warning when the module has hooks, no warning when no matching submodule entry-point exists, and a direct unit test of the warning method. |
Sequence Diagram
sequenceDiagram
participant User
participant Config as PytestPluginManager
participant EntryPoints as importlib.metadata
participant HookCheck as _plugin_has_pytest_hooks
participant WarnMethod as _warn_about_submodule_entrypoint_plugin
User->>Config: import_plugin(modname, consider_entry_points=True)
Config->>Config: load_setuptools_entrypoints("pytest11", name=modname)
alt entry-point loaded
Config-->>User: return (plugin registered via entry-point)
else no entry-point match
Config->>Config: __import__(modname)
Config->>Config: register(mod, modname)
Config->>WarnMethod: _warn_about_submodule_entrypoint_plugin(modname, mod)
WarnMethod->>HookCheck: _plugin_has_pytest_hooks(mod)
alt module has hooks
HookCheck-->>WarnMethod: True
WarnMethod-->>Config: return (no warning)
else module has no hooks
HookCheck-->>WarnMethod: False
WarnMethod->>EntryPoints: distributions()
EntryPoints-->>WarnMethod: list of distributions with entry-points
alt matching submodule entry-points found
WarnMethod->>User: emit PytestConfigWarning with suggestion
else no matching entry-points
WarnMethod-->>Config: return (no warning)
end
end
end
Dig Deeper With Commands
/review <file-path> <function-optional>/chat <file-path> "<question>"/roast <file-path>
Runs only when explicitly triggered.
| if ep.group == "pytest11" | ||
| and ep.name != modname | ||
| and isinstance(getattr(ep, "value", None), str) | ||
| and getattr(ep, "value").split(":", 1)[0].startswith(modname_prefix) |
There was a problem hiding this comment.
Iterates all installed distributions on every ambiguous check
importlib.metadata.distributions() scans all installed packages. This runs every time a -p loaded module has no hooks. Consider caching the result or using importlib.metadata.entry_points(group='pytest11') which is more targeted and faster on Python 3.12+.
| if ep.group == "pytest11" | ||
| and ep.name != modname | ||
| and isinstance(getattr(ep, "value", None), str) | ||
| and getattr(ep, "value").split(":", 1)[0].startswith(modname_prefix) |
There was a problem hiding this comment.
Double getattr call risks AttributeError on race
Line 920 checks getattr(ep, 'value', None) but line 921 calls getattr(ep, 'value') without default. If value is a property that could change or raise, this could throw. Use a single assignment: val = getattr(ep, 'value', None) then check isinstance(val, str) and val.split(...)....
Actionable Comments Posted: 2🧹 Nitpick comments (1)\`\_plugin\_has\_pytest\_hooks\` has no explicit return type path - src/_pytest/config/__init__.py (940)🧾 Coverage Summary✔️ Covered (3 files) |
|
/review --force |
Actionable Comments Posted: 0👀 Worth a Look (1)[MEDIUM] Hook detection can still raise on exotic plugin attributes - src/_pytest/config/__init__.py (938)🧹 Nitpick comments (1)Entry-point \`value\` is read twice in the new suggestion filter - src/_pytest/config/__init__.py (920)🧾 Coverage Summary✔️ Covered (3 files) |
Mirror of pytest-dev#14270
Summary by MergeMonkey